﻿using Artizan.Iot.Hub.Mqtt.AspNetCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.Threading;

namespace Artizan.Iot.Hub.Mqtt.HttpApi.Host.BackgroundServices;

public class MqttServerHostHeartbeatCallingWorker : AsyncPeriodicBackgroundWorkerBase
{
    public MqttServerHostHeartbeatCallingWorker(
        AbpAsyncTimer timer,
        IServiceScopeFactory serviceScopeFactory)
        : base(
            timer,
            serviceScopeFactory)
    {
        //Timer.Period = 60_000; //1 minute
        Timer.Period = 10_000; //10 second
    }

    protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
    {
        var configuration = workerContext.ServiceProvider.GetRequiredService<IConfiguration>();
        var httpClientFactory = workerContext.ServiceProvider.GetRequiredService<IHttpClientFactory>();
        var httpClient = httpClientFactory.CreateClient(IotHubMqttAspNetCoreConsts.MqttServerHostHeartbeatHttpClientName);

        /*--------------------------------------------------------------------------------
         如果 BackgroundWorker 内部发生异常, 但是没有捕获处理，将导致整个应用程序崩溃，
         所以使用 try...catch 捕获处理异常是必须的。
         --------------------------------------------------------------------------------*/
        try
        {
            var baseAddress = configuration.GetValue<string>("App:SelfUrl")?.TrimEnd('/');
            httpClient.BaseAddress = new Uri(baseAddress ?? "");

            // 发送 GET 请求到心跳接口
            var response = await httpClient.GetAsync(IotHubMqttAspNetCoreConsts.MqttServerHostHeartbeatUrl);

            // 检查响应是否成功
            if (response.IsSuccessStatusCode)
            {
                Logger.LogInformation("MQTT server host heartbeat sent successfully at: {time}", DateTimeOffset.Now);
            }
            else
            {
                Logger.LogError("Failed to send MQTT server host heartbeat. Status code: {statusCode}", response.StatusCode);
            }
        }
        catch (Exception ex)
        {
            Logger.LogError(ex, "An error occurred while sending MQTT server host heartbeat.");
            Logger.LogException(ex);
        }
        finally
        {
            httpClient.Dispose();
        }
    }
}
